Newer
Older
taehui / qwilight-fe / src / app / [language] / site / components / SiteInput.tsx
@Taehui Taehui on 6 Apr 3 KB 2024-04-07 오전 8:25
import wsAPI from "@/app/[language]/site/lib/wsAPI";
import { SiteView } from "@/app/[language]/site/state/setSiteStore";

import { useSiteStore } from "@/state/Stores";
import { observer } from "mobx-react-lite";
import { useTranslations } from "next-intl";
import InputGroup from "react-bootstrap/InputGroup";
import Button from "react-bootstrap/Button";
import { useQueryClient } from "@tanstack/react-query";
import FormControl from "react-bootstrap/FormControl";
import {
  ChatFill,
  Back,
  GearFill,
  PeopleFill,
  CloudUploadFill,
} from "react-bootstrap-icons";
import { forwardRef } from "react";

const EventPB = require("@/Event_pb");

export default observer(
  forwardRef<HTMLDivElement, { siteView: SiteView }>(function SiteInput(
    { siteView: { isEditable, textInput, setTextInput, setAvatarsViewOpened } },
    ref,
  ) {
    const { targetSiteID, setConfigureOpened, setSiteWindowOpened } =
      useSiteStore();
    const t = useTranslations();

    const postFile = (file: File) => {
      const fr = new FileReader();
      fr.readAsArrayBuffer(file);
      fr.addEventListener("loadend", () => {
        const { result } = fr;
        wsAPI.send({
          eventID: EventPB.Event.EventID.POST_FILE,
          text: file.name,
          data: [new Uint8Array(result as ArrayBufferLike)],
        });
      });
    };

    const queryClient = useQueryClient();

    return (
      <InputGroup ref={ref}>
        <Button
          variant="warning"
          onClick={() => {
            setConfigureOpened(true);
          }}
        >
          <GearFill />
        </Button>
        <Button
          onClick={() => {
            const inputElement = document.createElement("input");
            inputElement.type = "file";
            inputElement.accept = "audio/*,image/*,video/*";
            inputElement.addEventListener("change", ({ target }) => {
              const file = (target as HTMLInputElement).files?.[0];
              if (file) {
                postFile(file);
              }
            });
            inputElement.click();
          }}
        >
          <CloudUploadFill />
        </Button>
        <FormControl
          type="text"
          disabled={!isEditable}
          value={textInput}
          onChange={({ target: { value } }) => {
            setTextInput(value);
          }}
          onKeyDown={({ key }) => {
            if (key === "Enter") {
              if (textInput.length > 0) {
                wsAPI.send({
                  eventID: EventPB.Event.EventID.SITE_YELL,
                  text: JSON.stringify({
                    siteID: targetSiteID,
                    siteYell: textInput,
                  }),
                });
                setTextInput("");
              }
            }
          }}
          onPaste={({ clipboardData: { items } }) => {
            const data = items[0];
            if (data && data.kind === "file") {
              const file = data.getAsFile();
              if (file) {
                postFile(file);
              }
            }
          }}
        />
        <Button
          onClick={() => {
            setAvatarsViewOpened(true);
          }}
        >
          <PeopleFill />
        </Button>
        <Button
          onClick={async () => {
            await queryClient.invalidateQueries({ queryKey: ["sites"] });
            setSiteWindowOpened(true);
          }}
        >
          <ChatFill />
        </Button>
        {targetSiteID && (
          <Button
            variant="danger"
            onClick={() => {
              wsAPI.send({
                eventID: EventPB.Event.EventID.QUIT_SITE,
                text: targetSiteID,
              });
            }}
          >
            <Back />
          </Button>
        )}
      </InputGroup>
    );
  }),
);